/**
 *  Serponix is an arcade game in focus to multiplayer based on the classic game Snake.
 *  Copyright (C) 2010 - 2011  Daniel Vala
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License,
 *  or  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  If you have any question do not hesitate to contact author
 *  on e-mail address: danielvala42@gmail.com
 */
package com.serponix.game.projectiles;

import com.serponix.game.objektyNaPlose.VecNaPolicku;
import com.serponix.game.objektyNaPlose.Clanek;
import com.serponix.game.*;
import com.serponix.game.objektyNaPlose.ViceObjektu;
import com.serponix.game.objektyNaPlose.Zed;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import com.serponix.net.Informace;

/**
 * Laser je druh střely, který při nárazu zaniká. Hadovi přitom ničí jeden článek.
 * Pokud laser zanikne, hadovi se opět naplní zásobník a může vystřelit další laser.
 * Laser může být smrtící, což znamená, že při nárazu hada resetuje.
 * Laser se může i odrazit. Po 3 odrazu ale zaniká.
 * @author Daniel Vala
 */
public class Laser extends Projectile {

    private Color barva;
    private int poziceVZasobniku;
    private int pocetOdrazu;
    private boolean smrtici;

    public Laser(GameModel model, Snake had, int x, int y, Direction smer, int rychlost, int poziceVZasobniku, boolean smrtici) {
        super(model, had, x, y, smer, rychlost);
        this.poziceVZasobniku = poziceVZasobniku;
        this.smrtici = smrtici;
        if (smrtici) {
            barva = Color.GREEN;
        } else {
            this.barva = Color.RED;
        }
    }

    public boolean isSmrtici() {
        return smrtici;
    }

    /**
     * Laser se odrazí, tzn. změní směr na směr opačný.
     * // Laser vydrží jen 3 odrazy. Čtvrtý odraz laser zničí.
     * TODO nutnost předělat kolize - zatím laser vydrží nekonečno odrazů
     */
    public void odrazSe() {
        smer = Direction.obratSmer(smer);

//        if (pocetOdrazu < 3) {
//            smer = Smer.obratSmer(smer);
//            pocetOdrazu++;
//        } else {
//            znicSe();
//        }
    }

    /**
     *  Střela se odmapuje z herní plochy a nabije zásobník svému majiteli.
     *  Neodstraní se však ze seznamu střel v modelu.
     */
    @Override
    public void znicSe() {
        snake.nabijZasobnik(poziceVZasobniku);
        odmapuj(model);
    }

    @Override
    protected boolean kolize(int x, int y) {
        if (checkBorderCollision(x, y)) {
            return true;
        }

        VecNaPolicku vecPredStrelou = model.getObjektNaHerniPlose(x, y);
        if (vecPredStrelou != null) {
            if (vecPredStrelou instanceof ViceObjektu) {
                ViceObjektu viceObjektu = (ViceObjektu) vecPredStrelou;
                for (VecNaPolicku vecNaPolicku : viceObjektu.getVeciNaPolicku()) {
                    if (kolizeSObjektem(vecNaPolicku)) {
                        return true;
                    }
                }
                return false;
            } else {
                return kolizeSObjektem(vecPredStrelou);
            }
        }
        return false;
    }

    private boolean kolizeSObjektem(VecNaPolicku vecPredStrelou) {
        if (vecPredStrelou instanceof Clanek) {
            Clanek clanek = (Clanek) vecPredStrelou;
            if (clanek.getHad().zasah(this, clanek.getX(), clanek.getY())) {
                znicSe();
                return true;
            } else {
                return false; // pokud má had např. odolnost
            }
        } else if (vecPredStrelou instanceof Laser) {
            znicSe();
//            Laser laser = (Laser) vecPredStrelou;
//            laser.znicSeAOdstranSeZModelu();
            return true;
        } else if (vecPredStrelou instanceof Zed) {  // pokud střela narazila na stěnu mapy, zničí se
            znicSe();
            return true;
        } else {
            return false; // s jinými objekty kolize nevznikne
        }
    }

    private boolean checkBorderCollision(int x, int y) {
        if (model.isVHerniMape(x, y)) {
            return false;
        } else {
            znicSe();
            return true;
        }
    }

    public String getInstrukceProKresleni() {
        return Informace.LASER + Informace.ODDELOVAC3 + getX() + Informace.ODDELOVAC3 + getY() + Informace.ODDELOVAC3 + barva.getRGB() + Informace.ODDELOVAC3 + 0 + Informace.ODDELOVAC3 + Direction.prevedSmerNaCislo(smer) + Informace.ODDELOVAC2;
    }

    public static void paint(Graphics2D g2d, int x, int y, Direction smer) {
        x *= GameModel.getVelikostPolicka();
        y *= GameModel.getVelikostPolicka();

        if (smer == Direction.RIGHT || smer == Direction.LEFT) {
            g2d.fill3DRect(x + 2, y + 2, 25, 5, true);
        } else if (smer == Direction.UP || smer == Direction.DOWN) {
            g2d.fill3DRect(x + 2, y + 2, 5, 25, true);
        }
    }

    @Override
    public void draw(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setPaint(barva);
        paint(g2d, getX(), getY(), smer);
    }
}
